{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "view-in-github",
    "colab_type": "text"
   },
   "source": [
    "<a href=\"https://colab.research.google.com/github/alexfazio/crewAI-quickstart/blob/main/crewai_example_job_application_quickstart.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "hcXurPmTxP8G"
   },
   "source": "# Build a Crew to Tailor Job Applications"
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "tzycnDsPxP8H"
   },
   "source": [
    "If you're running this notebook on your own machine, you can install the following:\n",
    "```Python\n",
    "!pip install crewai==0.28.8 crewai_tools==0.1.6 langchain_community==0.0.29 --quiet\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 64,
    "id": "1wIqqeV5xP8H"
   },
   "source": [
    "# Warning control\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "EYNywIMWxP8I"
   },
   "source": [
    "- Import libraries, APIs and LLM"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 30,
    "id": "58ijamenxP8I"
   },
   "source": [
    "from crewai import Agent, Task, Crew"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "890Jk4-WxP8I"
   },
   "source": [
    "**Note**:\n",
    "- The video uses `gpt-4o`, but due to certain constraints, and in order to offer this course for free to everyone, the code you'll run here will use `gpt-3.5-turbo`.\n",
    "- You can use `gpt-4o` when you run the notebook _locally_ (using `gpt-4o` will not work on the platform)\n",
    "- Thank you for your understanding!"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 115,
    "id": "fGU39dLrxP8I"
   },
   "source": [
    "import os\n",
    "from utils import get_openai_api_key, get_serper_api_key\n",
    "\n",
    "openai_api_key = get_openai_api_key()\n",
    "os.environ[\"OPENAI_MODEL_NAME\"] = 'gpt-3.5-turbo'\n",
    "os.environ[\"SERPER_API_KEY\"] = get_serper_api_key()"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "HZzvRhNIxP8I"
   },
   "source": [
    "## crewAI Tools"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 200,
    "id": "yHT9O3rZxP8I"
   },
   "source": [
    "from crewai_tools import (\n",
    "  FileReadTool,\n",
    "  ScrapeWebsiteTool,\n",
    "  MDXSearchTool,\n",
    "  SerperDevTool\n",
    ")\n",
    "\n",
    "search_tool = SerperDevTool()\n",
    "scrape_tool = ScrapeWebsiteTool()\n",
    "read_resume = FileReadTool(file_path='./fake_resume.md')\n",
    "semantic_search_resume = MDXSearchTool(mdx='./fake_resume.md')"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "QUGqP_nXxP8I"
   },
   "source": [
    "- Uncomment and run the cell below if you wish to view `fake_resume.md` in the notebook."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 47,
    "id": "ZS6EphKVxP8I"
   },
   "source": [
    "# from IPython.display import Markdown, display\n",
    "# display(Markdown(\"./fake_resume.md\"))"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8ixHepiPxP8I"
   },
   "source": [
    "## Creating Agents"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 302,
    "id": "qYHx-zVWxP8I"
   },
   "source": [
    "# Agent 1: Researcher\n",
    "researcher = Agent(\n",
    "    role=\"Tech Job Researcher\",\n",
    "    goal=\"Make sure to do amazing analysis on \"\n",
    "         \"job posting to help job applicants\",\n",
    "    tools = [scrape_tool, search_tool],\n",
    "    verbose=True,\n",
    "    backstory=(\n",
    "        \"As a Job Researcher, your prowess in \"\n",
    "        \"navigating and extracting critical \"\n",
    "        \"information from job postings is unmatched.\"\n",
    "        \"Your skills help pinpoint the necessary \"\n",
    "        \"qualifications and skills sought \"\n",
    "        \"by employers, forming the foundation for \"\n",
    "        \"effective application tailoring.\"\n",
    "    )\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 285,
    "id": "ySOpFa91xP8I"
   },
   "source": [
    "# Agent 2: Profiler\n",
    "profiler = Agent(\n",
    "    role=\"Personal Profiler for Engineers\",\n",
    "    goal=\"Do increditble research on job applicants \"\n",
    "         \"to help them stand out in the job market\",\n",
    "    tools = [scrape_tool, search_tool,\n",
    "             read_resume, semantic_search_resume],\n",
    "    verbose=True,\n",
    "    backstory=(\n",
    "        \"Equipped with analytical prowess, you dissect \"\n",
    "        \"and synthesize information \"\n",
    "        \"from diverse sources to craft comprehensive \"\n",
    "        \"personal and professional profiles, laying the \"\n",
    "        \"groundwork for personalized resume enhancements.\"\n",
    "    )\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 268,
    "id": "NSa4ejthxP8J"
   },
   "source": [
    "# Agent 3: Resume Strategist\n",
    "resume_strategist = Agent(\n",
    "    role=\"Resume Strategist for Engineers\",\n",
    "    goal=\"Find all the best ways to make a \"\n",
    "         \"resume stand out in the job market.\",\n",
    "    tools = [scrape_tool, search_tool,\n",
    "             read_resume, semantic_search_resume],\n",
    "    verbose=True,\n",
    "    backstory=(\n",
    "        \"With a strategic mind and an eye for detail, you \"\n",
    "        \"excel at refining resumes to highlight the most \"\n",
    "        \"relevant skills and experiences, ensuring they \"\n",
    "        \"resonate perfectly with the job's requirements.\"\n",
    "    )\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 285,
    "id": "sIAKXl5gxP8J"
   },
   "source": [
    "# Agent 4: Interview Preparer\n",
    "interview_preparer = Agent(\n",
    "    role=\"Engineering Interview Preparer\",\n",
    "    goal=\"Create interview questions and talking points \"\n",
    "         \"based on the resume and job requirements\",\n",
    "    tools = [scrape_tool, search_tool,\n",
    "             read_resume, semantic_search_resume],\n",
    "    verbose=True,\n",
    "    backstory=(\n",
    "        \"Your role is crucial in anticipating the dynamics of \"\n",
    "        \"interviews. With your ability to formulate key questions \"\n",
    "        \"and talking points, you prepare candidates for success, \"\n",
    "        \"ensuring they can confidently address all aspects of the \"\n",
    "        \"job they are applying for.\"\n",
    "    )\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5OZMTPI_xP8J"
   },
   "source": [
    "## Creating Tasks"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 268,
    "id": "dVD0T4ddxP8J"
   },
   "source": [
    "# Task for Researcher Agent: Extract Job Requirements\n",
    "research_task = Task(\n",
    "    description=(\n",
    "        \"Analyze the job posting URL provided ({job_posting_url}) \"\n",
    "        \"to extract key skills, experiences, and qualifications \"\n",
    "        \"required. Use the tools to gather content and identify \"\n",
    "        \"and categorize the requirements.\"\n",
    "    ),\n",
    "    expected_output=(\n",
    "        \"A structured list of job requirements, including necessary \"\n",
    "        \"skills, qualifications, and experiences.\"\n",
    "    ),\n",
    "    agent=researcher,\n",
    "    async_execution=True\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 285,
    "id": "DN4VNi6FxP8J"
   },
   "source": [
    "# Task for Profiler Agent: Compile Comprehensive Profile\n",
    "profile_task = Task(\n",
    "    description=(\n",
    "        \"Compile a detailed personal and professional profile \"\n",
    "        \"using the GitHub ({github_url}) URLs, and personal write-up \"\n",
    "        \"({personal_writeup}). Utilize tools to extract and \"\n",
    "        \"synthesize information from these sources.\"\n",
    "    ),\n",
    "    expected_output=(\n",
    "        \"A comprehensive profile document that includes skills, \"\n",
    "        \"project experiences, contributions, interests, and \"\n",
    "        \"communication style.\"\n",
    "    ),\n",
    "    agent=profiler,\n",
    "    async_execution=True\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "EXtk-QxWxP8J"
   },
   "source": [
    "- You can pass a list of tasks as `context` to a task.\n",
    "- The task then takes into account the output of those tasks in its execution.\n",
    "- The task will not run until it has the output(s) from those tasks."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 353,
    "id": "A2WW6bu8xP8J"
   },
   "source": [
    "# Task for Resume Strategist Agent: Align Resume with Job Requirements\n",
    "resume_strategy_task = Task(\n",
    "    description=(\n",
    "        \"Using the profile and job requirements obtained from \"\n",
    "        \"previous tasks, tailor the resume to highlight the most \"\n",
    "        \"relevant areas. Employ tools to adjust and enhance the \"\n",
    "        \"resume content. Make sure this is the best resume even but \"\n",
    "        \"don't make up any information. Update every section, \"\n",
    "        \"inlcuding the initial summary, work experience, skills, \"\n",
    "        \"and education. All to better reflrect the candidates \"\n",
    "        \"abilities and how it matches the job posting.\"\n",
    "    ),\n",
    "    expected_output=(\n",
    "        \"An updated resume that effectively highlights the candidate's \"\n",
    "        \"qualifications and experiences relevant to the job.\"\n",
    "    ),\n",
    "    output_file=\"tailored_resume.md\",\n",
    "    context=[research_task, profile_task],\n",
    "    agent=resume_strategist\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 336,
    "id": "PXzulUiExP8J"
   },
   "source": [
    "# Task for Interview Preparer Agent: Develop Interview Materials\n",
    "interview_preparation_task = Task(\n",
    "    description=(\n",
    "        \"Create a set of potential interview questions and talking \"\n",
    "        \"points based on the tailored resume and job requirements. \"\n",
    "        \"Utilize tools to generate relevant questions and discussion \"\n",
    "        \"points. Make sure to use these question and talking points to \"\n",
    "        \"help the candiadte highlight the main points of the resume \"\n",
    "        \"and how it matches the job posting.\"\n",
    "    ),\n",
    "    expected_output=(\n",
    "        \"A document containing key questions and talking points \"\n",
    "        \"that the candidate should prepare for the initial interview.\"\n",
    "    ),\n",
    "    output_file=\"interview_materials.md\",\n",
    "    context=[research_task, profile_task, resume_strategy_task],\n",
    "    agent=interview_preparer\n",
    ")\n"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "HKikwROGxP8J"
   },
   "source": [
    "## Creating the Crew"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 234,
    "id": "RgjsRM3hxP8J"
   },
   "source": [
    "job_application_crew = Crew(\n",
    "    agents=[researcher,\n",
    "            profiler,\n",
    "            resume_strategist,\n",
    "            interview_preparer],\n",
    "\n",
    "    tasks=[research_task,\n",
    "           profile_task,\n",
    "           resume_strategy_task,\n",
    "           interview_preparation_task],\n",
    "\n",
    "    verbose=True\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NUGsLRgFxP8J"
   },
   "source": [
    "## Running the Crew\n",
    "\n",
    "- Set the inputs for the execution of the crew."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 232,
    "id": "Nbwo_DPlxP8J"
   },
   "source": [
    "job_application_inputs = {\n",
    "    'job_posting_url': 'https://jobs.lever.co/AIFund/6c82e23e-d954-4dd8-a734-c0c2c5ee00f1?lever-origin=applied&lever-source%5B%5D=AI+Fund',\n",
    "    'github_url': 'https://github.com/joaomdmoura',\n",
    "    'personal_writeup': \"\"\"Noah is an accomplished Software\n",
    "    Engineering Leader with 18 years of experience, specializing in\n",
    "    managing remote and in-office teams, and expert in multiple\n",
    "    programming languages and frameworks. He holds an MBA and a strong\n",
    "    background in AI and data science. Noah has successfully led\n",
    "    major tech initiatives and startups, proving his ability to drive\n",
    "    innovation and growth in the tech industry. Ideal for leadership\n",
    "    roles that require a strategic and innovative approach.\"\"\"\n",
    "}"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "eiMJYOu8xP8J"
   },
   "source": [
    "**Note**: LLMs can provide different outputs for they same input, so what you get might be different than what you see in the video."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 47,
    "id": "lP7fPn_cxP8J"
   },
   "source": [
    "### this execution will take a few minutes to run\n",
    "result = job_application_crew.kickoff(inputs=job_application_inputs)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gfOXojlqxP8J"
   },
   "source": [
    "- Dislplay the generated `tailored_resume.md` file."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 47,
    "id": "DKG5oTQSxP8J",
    "ExecuteTime": {
     "end_time": "2024-07-22T14:36:13.625766Z",
     "start_time": "2024-07-22T14:36:13.621098Z"
    }
   },
   "source": [
    "# @title 🖥️ Display the results of your crew as markdown\n",
    "from IPython.display import Markdown, display\n",
    "display(Markdown(\"./tailored_resume.md\"))"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ],
      "text/markdown": "./tailored_resume.md"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "tt39acNtxP8J"
   },
   "source": [
    "- Dislplay the generated `interview_materials.md` file."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "height": 30,
    "id": "zEya5MeExP8J"
   },
   "source": [
    "# @title 🖥️ Display the results of your crew as markdown\n",
    "from IPython.display import display, Markdown\n",
    "\n",
    "markdown_text = result.raw  # Adjust this based on the actual attribute\n",
    "\n",
    "# Display the markdown content\n",
    "display(Markdown(markdown_text))"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Dpz3Lt4qxP8J"
   },
   "source": ""
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  },
  "colab": {
   "provenance": [],
   "include_colab_link": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
